﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using System.Drawing;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business;

namespace blackhouse.BlackApart.Web {
    public static class UrlUtils {

        #region Fields

        private static bool set = false;
        private static bool useUrlRewriting = true;
        private static string parameterApartmentId = "apartment";
        private static string parameterApartmentTypeId = "apartmentType";
        private static string parameterApartmentTypeView = "view";
        private static string parameterPage = "page";
        private static string parameterArrival = "arrival";
        private static string parameterDeparture = "departure";
        private static string parameterPersons = "persons";
        private static string parameterReservationNumber = "number";

        #endregion

        #region Properties

        public static string ParameterReservationNumber {
            get {
                Set();
                return parameterReservationNumber;
            }
            private set {
                Set();
                parameterReservationNumber = value;
            }
        }

        public static string ParameterArrival {
            get {
                Set();
                return parameterArrival;
            }
            private set {
                Set();
                parameterArrival = value;
            }
        }

        public static string ParameterDeparture {
            get {
                Set();
                return parameterDeparture;
            }
            private set {
                Set();
                parameterDeparture = value;
            }
        }

        public static string ParameterPersons {
            get {
                Set();
                return parameterPersons;
            }
            private set {
                Set();
                parameterPersons = value;
            }
        }

        public static string ParameterApartmentId {
            get {
                Set();
                return parameterApartmentId;
            }
            private set {
                Set();
                parameterApartmentId = value;
            }
        }

        public static string ParameterApartmentTypeId {
            get {
                Set();
                return parameterApartmentTypeId;
            }
            private set {
                Set();
                parameterApartmentTypeId = value;
            }
        }

        public static string ParameterApartmentTypeView {
            get {
                Set();
                return parameterApartmentTypeView;
            }
            private set {
                Set();
                parameterApartmentTypeView = value;
            }
        }

        public static string ParameterPage {
            get {
                Set();
                return parameterPage;
            }
            private set {
                Set();
                parameterPage = value;
            }
        }

        /// <summary>
        /// Defines whether to use the override. Default value is true. You can change this by setting the value for appSetting["UseUrlRewriting"]
        /// </summary>
        public static bool UseUrlRewriting {
            get {
                Set();
                return useUrlRewriting;
            }
            private set {
                Set();
                useUrlRewriting = value;
            }
        }

        #endregion

        #region Methods

        private static void Set() {
            if (!set) {
                string cManUseUR = ConfigurationManager.AppSettings["UseUrlRewriting"];
                useUrlRewriting = !(cManUseUR == "false");
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterApartmentTypeId"]))
                    parameterApartmentTypeId = ConfigurationManager.AppSettings["ParameterApartmentTypeId"];
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterApartmentId"]))
                    parameterApartmentId = ConfigurationManager.AppSettings["ParameterApartmentId"];
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterApartmentTypeView"]))
                    parameterApartmentTypeView = ConfigurationManager.AppSettings["ParameterApartmentTypeView"];
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterPage"]))
                    parameterPage = ConfigurationManager.AppSettings["ParameterPage"];
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterArrival"]))
                    parameterArrival = ConfigurationManager.AppSettings["ParameterArrival"];
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterDeparture"]))
                    parameterDeparture = ConfigurationManager.AppSettings["ParameterDeparture"];
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterPersons"]))
                    parameterPersons = ConfigurationManager.AppSettings["ParameterPersons"];
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["ParameterReservationNumber"]))
                    parameterReservationNumber = ConfigurationManager.AppSettings["ParameterReservationNumber"];
            }
        }

        public static string FurnitureImageUrl(string fileName) {
            return FurnitureImageUrl(fileName, ImageSizeUtils.FurnitureSize);
        }

        public static string FurnitureImageUrl(string fileName, Size size) {
            return GetDbImageUrl("Furniture", fileName, size);
        }

        public static string ApartmentPhotoSmallImageUrl(string fileName) {
            return ApartmentPhotoSmallImageUrl(fileName, ImageSizeUtils.ApartmentPhotoSmall);
        }

        public static string ApartmentPhotoBigImageUrl(string fileName) {
            return GetDbImageUrl("Apartment-photo", fileName, ImageSizeUtils.ApartmentPhotoFull);
        }

        public static string ApartmentPhotoPrototypeImageUrl(string fileName) {
            return GetDbImageUrl("Apartment-photo", fileName, new Size(0, 0));
        }

        public static string ApartmentPhotoSmallImageUrl(string fileName, Size size) {
            return GetDbImageUrl("Apartment-photo", fileName, size);
        }

        public static string ApartmentBannerImageUrl(string fileName) {
            return ApartmentBannerImageUrl(fileName, ImageSizeUtils.ApartmentBanner);
        }

        public static string ApartmentBannerImageUrl(string fileName, Size size) {
            return GetDbImageUrl("Apartment-banner", fileName, size);
        }

        public static string ApartmentPhotoReservationImageUrl(string fileName) {
            return ApartmentPhotoReservationImageUrl(fileName, ImageSizeUtils.ApartmentPhotoReservation);
        }

        public static string ApartmentPhotoReservationImageUrl(string fileName, Size size) {
            return GetDbImageUrl("Apartment-photo", fileName, size);
        }

        public static string GetDbImageUrl(string config, string fileName, Size size) {
            if (UseUrlRewriting)
                return string.Format("/DbFile/{0}/{1}x{2}/{3}", config, size.Width, size.Height, fileName);
            else
                return string.Format("/NemoDynamicImage.ashx?configuration={0}&width={1}&height={2}&file={3}", config, size.Width, size.Height, fileName);
        }

        private static string FormatPreFolderEv(string preFolderEv) {
            if (string.IsNullOrEmpty(preFolderEv) || preFolderEv == "/")
                preFolderEv = "";
            else {
                preFolderEv = preFolderEv.TrimEnd('/');
                if (!preFolderEv.StartsWith("/"))
                    preFolderEv = "/" + preFolderEv;
            }
            return preFolderEv;
        }

        private static string FormatUrl(string url) {
            return url.ToLower().TrimEnd(',');
        }

        public static string GetApartmentTypeUrl(IApartmentGroup group, DisplayApartmentTypeView view, int page, SearchState state) {
            return GetApartmentTypeUrl(Factory.Instance().GetPreFolderEvaluation(), group, DisplayApartmentTypeView.Default, page, state);
        }

        public static string GetApartmentTypeUrl(IApartmentGroup group, DisplayApartmentTypeView view, int page) {
            return GetApartmentTypeUrl(Factory.Instance().GetPreFolderEvaluation(), group, DisplayApartmentTypeView.Default, page, SearchState.GetFromContext());
        }

        public static string GetApartmentTypeUrl(string preFolderEv, IApartmentGroup group, DisplayApartmentTypeView view, int page) {
            return GetApartmentTypeUrl(preFolderEv, group, DisplayApartmentTypeView.Default, page, SearchState.GetFromContext());
        }

        public static string GetApartmentTypeUrl(string preFolderEv, IApartmentGroup group, DisplayApartmentTypeView view, int page, SearchState state) {
            preFolderEv = FormatPreFolderEv(preFolderEv);
            if (page == 0) page = 1;

            if (UseUrlRewriting) {
                string url = preFolderEv;
                url = url + '/' + group.GetSeo().PageTitle.ReplaceEx("|", "-").CleanStringForUrl().RemovePolishChars().ReplaceEx(",", "-");
                url = url + ',' + group.Id;
                url = url + ',' + view;
                url = url + ',' + page;
                if (state.IsSet)
                    url = url + ',' + state.ToString();
                return FormatUrl(url);
            }
            else {
                string url = preFolderEv;
                url += "/displayapartment.aspx?" + parameterApartmentTypeId + "=" + group.Id;
                if (view != DisplayApartmentTypeView.Default)
                    url += "&" + ParameterApartmentTypeView + "=" + view;
                if (page > 1)
                    url += "&" + ParameterPage + "=" + page;
                if (state.IsSet)
                    url += "&search=" + state.ToString();
                return url.ToLower();
            }
        }

        public static string GetOpinionsUrl(string preFolderEv, IApartmentGroup group, IApartment apartment, int page) {
            preFolderEv = FormatPreFolderEv(preFolderEv);
            if (UseUrlRewriting) {
                // 0 - grupa nazwa
                // 1- warunek dla przecinka, jeżeli grupa i apartament są sprecyzowane przecinek jest
                // 2 - apartament nazwa
                // 3 - grupa id
                // 4 - apartament id
                // 5 - warunek dla przecinka, jeżeli strona > 1 to dodaj przecinek
                // 6 - strona
                return string.Format("{7}/{0}{1}{2}-opinions-{3},{4}{5}{6}",
                    (group != null) ? group.Name.CleanStringForUrl() : "", // 0
                    (group != null && apartment != null) ? "," : "", // 1
                    (apartment != null) ? apartment.Name.CleanStringForUrl() : "", // 2
                    (group != null) ? group.Id.ToString() : "0", // 3
                    (apartment != null) ? apartment.Id.ToString() : "0", // 4
                    (page > 1) ? "," : "", // 5
                    (page > 1) ? page.ToString() : "",
                    preFolderEv) // 6
                    .ToLower();
            }
            else {
                return string.Format("/Pages/DisplayOpinion.aspx?type={0}&apartment={1}&page={2}", (group != null) ? group.Id.ToString() : "0", (apartment != null) ? apartment.Id.ToString() : "0", page);
            }
        }

        public static string GetReservationUrl(string preFolderEv, DateTime arrivalDate, DateTime departureDate, int personCount, IApartmentGroup apartmentType) {
            return GetReservationUrl(preFolderEv, arrivalDate, departureDate, personCount, apartmentType.Id, apartmentType.Name);
        }

        public static string GetReservationUrl(string preFolderEv, DateTime arrivalDate, DateTime departureDate, int personCount, int apartmentTypeId) {
            Factory factory = Factory.Instance();
            IApartmentGroup group = null;
            if (apartmentTypeId > 0)
                group = factory.GetApartmentGroup(apartmentTypeId);

            string name = HttpContext.GetGlobalResourceObject("Aparts", "findFreeApartments").ToString();

            if (group != null && group.Id == apartmentTypeId)
                name = group.Name.CleanStringForUrl();

            return GetReservationUrl(preFolderEv, arrivalDate, departureDate, personCount, apartmentTypeId, name);
        }

        public static string LocalizeUrl(string relativeUrl) {
            return LocalizeUrl(Factory.Instance().GetPreFolderEvaluation(), relativeUrl);
        }

        public static string LocalizeUrl(string preFolderEv, string relativeUrl) {
            preFolderEv = FormatPreFolderEv(preFolderEv);
            if (!relativeUrl.StartsWith("/"))
                relativeUrl = "/" + relativeUrl;
            if (relativeUrl.StartsWith(preFolderEv))
                return relativeUrl;
            else
                return preFolderEv + relativeUrl;
        }

        public static string GetReservationUrl(string preFolderEv, DateTime arrivalDate, DateTime departureDate, int personCount, int apartmentTypeId, string apartmentName) {
            preFolderEv = FormatPreFolderEv(preFolderEv);
            if (UseUrlRewriting) {
                return string.Format("{5}/{0}-reservations-{1},{2},{3},{4}",
                    string.IsNullOrEmpty(apartmentName) ? "pokaz-wolne-pokoje" : apartmentName,
                    apartmentTypeId == 0 ? "" : apartmentTypeId.ToString(),
                    arrivalDate == DateTime.MinValue ? "" : arrivalDate.ToString("yyyyMMdd"),
                    departureDate == DateTime.MinValue ? "" : departureDate.ToString("yyyyMMdd"),
                    personCount,
                    preFolderEv
                    ).ToLower();
            }
            else {
                return string.Format("/Pages/Reservation.aspx?{4}={0}&arrival={1}&departure={2}&persons={3}", apartmentTypeId, arrivalDate == DateTime.MinValue ? "" : arrivalDate.ToString("yyyyMMdd"), departureDate == DateTime.MinValue ? "" : departureDate.ToString("yyyyMMdd"), personCount, ParameterApartmentTypeId);
            }
        }

        #endregion

    }
}